package com.hoangqp.lookdict;

import com.cybozu.labs.langdetect.Detector;
import com.cybozu.labs.langdetect.DetectorFactory;
import com.cybozu.labs.langdetect.LangDetectException;
import com.cybozu.labs.langdetect.Language;
import com.hoangqp.lookdict.R;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import com.hoangqp.android.database.DatabaseHandler;
import com.hoangqp.android.stardictcore.FileTooBigException;
import com.hoangqp.android.stardictcore.StarDictParser;
import com.hoangqp.android.stardictcore.WordDataItem;
import com.hoangqp.android.stardictcore.WordEntry;
import com.hoangqp.lookdict.adapter.CustomListViewAdapter;
import com.hoangqp.stardict.parse.WrongPropertyException;
import com.hoangqp.util.CaculateScreenSize;
import com.hoangqp.util.Utils;
import com.hoangqp.util.WildCardCompare;

import android.os.AsyncTask;
import android.os.Bundle;
import android.app.Activity;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.support.v4.app.Fragment;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.view.Window;
import android.view.WindowManager;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodManager;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;

public class TOPActivity extends Fragment {

	public static final String PATH_FILE = "PATH_FILE";

	// Height Status Bar
	private static final int LOW_DPI_STATUS_BAR_HEIGHT = 19;
	private static final int MEDIUM_DPI_STATUS_BAR_HEIGHT = 25;
	private static final int HIGH_DPI_STATUS_BAR_HEIGHT = 38;

	// UI Elements
	private ListView listView = null;
	private EditText edtSearch = null;
	private Button btnSearch = null;
	private ImageView imageSmile = null;
	private ImageView imageBorring = null;

	private ArrayList<WordEntry> listArray = new ArrayList<WordEntry>();

	private CustomListViewAdapter listAdapter;

	private static StarDictParser starDictParser;
	// StarDict starDict;

	private List<WordEntry> entries = new ArrayList<WordEntry>();

	private int HEIGHT_OF_ACTIONBAR;

	private Detector dectector;

	// Database
	private DatabaseHandler dataBaseHandler;
	private int bookId;

	/*
	 * ------------------------------------ Activity lifecycle
	 * --------------------------------------------------
	 */

	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {

		View rootView = inflater.inflate(R.layout.top_activity, container,
				false);

		imageSmile = (ImageView) rootView.findViewById(R.id.img_felling_smile);
		imageBorring = (ImageView) rootView
				.findViewById(R.id.img_felling_boring);

		actionUI(rootView);

		/** list view */

		// set height for list view
		listView = (ListView) rootView.findViewById(R.id.list_dict);
		// listHistoryView = (ListView)
		// rootView.findViewById(R.id.list_history);

		return rootView;
	}

	@Override
	public void onActivityCreated(Bundle savedInstanceState) {
		super.onActivityCreated(savedInstanceState);

		dataBaseHandler = new DatabaseHandler(getActivity());
		bookId = getBookId(Utils.PATH_FILE_VALUE);
		
		listAdapter = new CustomListViewAdapter(getActivity(),
				R.layout.custom_row, listArray, bookId, dataBaseHandler);

		setListenerOnList();

		LoadFileFormSDCard loadFile = new LoadFileFormSDCard();
		loadFile.execute(Utils.PATH_FILE_VALUE);

	}

	// get book id
	private int getBookId(String pathOfFile){
		int bookId = dataBaseHandler.getBookIdWithPath(pathOfFile);
		return bookId;
	}
	protected void performSearch() {
		// TODO Auto-generated method stub

		String txtString = edtSearch.getText().toString();

		// check is wild card
		if (txtString.contains("?") || txtString.contains("*")) {
			ArrayList<WordEntry> items = new ArrayList<WordEntry>();
			items = findWithWildCards(txtString);
			listArray.clear();
			if (items.size() > 0) {
				for (WordEntry entry : items) {
					listArray.add(entry);
				}

			} else {
				// Animation fadeInAnimation =
				// AnimationUtils.loadAnimation(getActivity(),
				// R.anim.image_fadein);
			}
		} else {
			long indexOfString = findIndexForWord(txtString);
			listArray.clear();
			if (indexOfString != -1) {
				WordEntry entry = entries.get((int) indexOfString);
				listArray.add(entry);
			} else {

			}
		}

		getActivity().runOnUiThread(new Runnable() {

			@Override
			public void run() {
				// TODO Auto-generated method stub
				if (listArray.size() > 0) {
					imageSmile.setVisibility(View.GONE);
					imageBorring.setVisibility(View.GONE);

					listAdapter.notifyDataSetChanged();
					listView.setAdapter(listAdapter);
				} else {
					Animation fadeOutAnimation = AnimationUtils.loadAnimation(
							getActivity(), R.anim.image_fadein);
					imageSmile.setVisibility(View.GONE);
					imageBorring.setVisibility(View.VISIBLE);
					imageBorring.startAnimation(fadeOutAnimation);
				}
			}
		});

	}

	// @Override
	// protected void onStart() {
	// // TODO Auto-generated method stub
	// super.onStart();
	// }
	//
	// @Override
	// protected void onStop() {
	// // TODO Auto-generated method stub
	// super.onStop();
	// }

	@Override
	public void onDestroy() {
		super.onDestroy();
		listAdapter.clear();
		listArray.clear();

		if (listAdapter.getSpeaker() != null) {
			listAdapter.getSpeaker().stop();
			listAdapter.getSpeaker().shutdown();
		}

		System.gc();
	}

	/**
	 * Convert dp to pixel
	 */
	public int convertDpToPixel(float dp) {
		DisplayMetrics metrics = getResources().getDisplayMetrics();
		float px = dp * (metrics.densityDpi / 160f);
		return (int) px;
	}

	private void setListenerOnList() {
		// 1. click on item
		listView.setOnItemClickListener(new OnItemClickListener() {

			@Override
			public void onItemClick(AdapterView<?> parent, View arg1,
					int position, long arg3) {
				// TODO Auto-generated method stub
				WordEntry item = (WordEntry) parent.getItemAtPosition(position);
				showDialog(getActivity(), item);
			}
		});
	}

	private int heightStatusBar() {
		DisplayMetrics displayMetrics = new DisplayMetrics();
		((WindowManager) getActivity().getSystemService(Context.WINDOW_SERVICE))
				.getDefaultDisplay().getMetrics(displayMetrics);

		int statusBarHeight;

		switch (displayMetrics.densityDpi) {
		case DisplayMetrics.DENSITY_HIGH:
			statusBarHeight = HIGH_DPI_STATUS_BAR_HEIGHT;
			break;
		case DisplayMetrics.DENSITY_MEDIUM:
			statusBarHeight = MEDIUM_DPI_STATUS_BAR_HEIGHT;
			break;
		case DisplayMetrics.DENSITY_LOW:
			statusBarHeight = LOW_DPI_STATUS_BAR_HEIGHT;
			break;
		default:
			statusBarHeight = MEDIUM_DPI_STATUS_BAR_HEIGHT;
		}
		return statusBarHeight;
	}

	private int heigtActionBar() {
		return HEIGHT_OF_ACTIONBAR;
	}

	/**
	 * Show meaning view
	 * 
	 * @param context
	 * @param item
	 */
	private void showDialog(final Context context, WordEntry item) {
		CaculateScreenSize sizeOfScreen = new CaculateScreenSize(
				(Activity) context);

		LinearLayout viewGroup = (LinearLayout) ((Activity) context)
				.findViewById(R.id.popup_element);
		LayoutInflater inflater = (LayoutInflater) context
				.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
		View layout = inflater.inflate(R.layout.top_popup, viewGroup);

		// Create custom dialog object
		final Dialog dialog = new Dialog(context, R.style.DialogAnimation);

		dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
		// Include dialog.xml file
		dialog.setContentView(layout);
		// Set dialog title
		// dialog.setTitle("Custom Dialog");
		dialog.getWindow().setBackgroundDrawable(
				new ColorDrawable(android.graphics.Color.TRANSPARENT));

		dialog.getWindow().setLayout(
				LayoutParams.MATCH_PARENT,
				sizeOfScreen.heightScreen() - heightStatusBar()
						- heigtActionBar());
		// set values for custom dialog components - text, image and button
		TextView txtView = (TextView) layout.findViewById(R.id.txt_title);
		txtView.setText(item.getStrWord());

		TextView txtMeaning = (TextView) layout.findViewById(R.id.txtView);

		try {
			txtMeaning.setText(lookupWord(item));
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		ImageButton close = (ImageButton) layout
				.findViewById(R.id.btn_close_popup);
		close.setBackgroundColor(Color.alpha(0));
		close.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				dialog.dismiss();
			}
		});

		dialog.show();
	}

	/** progress load data */
	private ProgressDialog pDialog;

	// Load file from sdcard
	private class LoadFileFormSDCard extends AsyncTask<String, Void, Void> {

		@Override
		protected void onPreExecute() {
			super.onPreExecute();

			pDialog = new ProgressDialog(getActivity());

			// pDialog.setContentView(view);
			pDialog.setMessage("Please wait...");
			pDialog.setIndeterminate(false);
			pDialog.setCancelable(false);
			pDialog.show();
		}

		@Override
		protected Void doInBackground(String... params) {
			// TODO Auto-generated method stub

			try {
				try {
					loadFile(params[0]);
				} catch (FileTooBigException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (WrongPropertyException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			return null;
		}

		@Override
		protected void onPostExecute(Void result) {
			// TODO Auto-generated method stub
			super.onPostExecute(result);
			pDialog.dismiss();

			Thread detectLanguageThread = new Thread(null, new Runnable() {

				@Override
				public void run() {
					// TODO Auto-generated method stub
					boolean loop = false;
					do {
						if (entries.size() > 0) {
							loop = true;
							String word = entries.get(entries.size() / 2)
									.getStrWord();
							try {
								detectStringLanguage(word);
							} catch (LangDetectException e) {
								// TODO Auto-generated catch block
								e.printStackTrace();
							}
						}
					} while (!loop);
				}
			});
			detectLanguageThread.start();

			getActivity().runOnUiThread(new Runnable() {

				@Override
				public void run() {
					// TODO Auto-generated method stub
					Animation fadeInAnimation = AnimationUtils.loadAnimation(
							getActivity(), R.anim.image_fadein);
					imageSmile.setVisibility(View.VISIBLE);
					imageSmile.startAnimation(fadeInAnimation);
				}
			});
		}

	}

	//
	private void loadFile(String path) throws IOException,
			WrongPropertyException, FileTooBigException {
		starDictParser = new StarDictParser(Utils.PATH_FILE_VALUE,
				getActivity().getBaseContext());
		entries = starDictParser.getWordEntry();
	}

	/**
	 * get meaning
	 * 
	 * @throws IOException
	 * @throws FileNotFoundException
	 */
	private String lookupWord(WordEntry item) throws FileNotFoundException,
			IOException {
		String meaning = null;
		List<WordDataItem> dataItem = new ArrayList<WordDataItem>();

		dataItem = starDictParser.getWordDatas(item);

		meaning = dataItem.get(0).convertWordDataToHtml();
		return meaning;
	}

	/*
	 * ----------------------------------------------------------------- key
	 * board ------------------------------------------------------------------
	 */
	/**
	 * Hides the soft keyboard
	 */
	public void hideSoftKeyboard() {
		if (getActivity().getCurrentFocus() != null) {
			InputMethodManager inputMethodManager = (InputMethodManager) getActivity()
					.getSystemService(Activity.INPUT_METHOD_SERVICE);
			inputMethodManager.hideSoftInputFromWindow(getActivity()
					.getCurrentFocus().getWindowToken(), 0);
		}
	}

	/**
	 * Shows the soft keyboard
	 */
	// public void showSoftKeyboard(View view) {
	// InputMethodManager inputMethodManager = (InputMethodManager)
	// getSystemService(INPUT_METHOD_SERVICE);
	// view.requestFocus();
	// inputMethodManager.showSoftInput(view, 0);
	// }

	/**
	 * return the index of a word in entry list.
	 * 
	 * @param word
	 *            the chosen word
	 * @return index of this word
	 */
	public long findIndexForWord(String word) {
		// if (!boolIsLoaded)
		// return longWordCount;
		long first = 0;
		long last = (int) entries.size() - 1;
		long mid;
		String lwrWord = word.toLowerCase();
		// use binary search
		do {
			mid = (first + last) / 2;
			int cmp = lwrWord.compareTo(((WordEntry) entries.get((int) mid))
					.getStrLwrWord());
			if (cmp == 0) {
				return mid; // return index if found
			}
			if (cmp > 0) {
				first = mid + 1;
			} else {
				last = mid - 1;
			}
		} while (first <= last);
		// if not found
		/*
		 * if (first < longWordCount) { while (first < longWordCount) { if
		 * (((WordEntry) entryList.get( (int)
		 * first)).getStrLwrWord().compareTo(lwrWord) > 0) { break; } else {
		 * first++; } } }
		 */
		first = -1;
		return first;
	}

	public ArrayList<WordEntry> findWithWildCards(String regex) {

		ArrayList<WordEntry> wordEntries = new ArrayList<WordEntry>();
		WildCardCompare wildCard = new WildCardCompare();
		for (WordEntry entry : entries) {
			if (wildCard.compare(entry.getStrWord(), regex)) {
				wordEntries.add(entry);
			}

		}

		return wordEntries;
	}

	public int getStatusBarHeight() {
		int result = 0;
		int resourceId = getResources().getIdentifier("status_bar_height",
				"dimen", "android");
		if (resourceId > 0) {
			result = getResources().getDimensionPixelSize(resourceId);
		}
		return result;
	}

	private void actionUI(View rootView) {
		/** Edit text */
		edtSearch = (EditText) rootView.findViewById(R.id.txt_seach_words);
		edtSearch
				.setOnEditorActionListener(new TextView.OnEditorActionListener() {

					@Override
					public boolean onEditorAction(TextView v, int actionId,
							KeyEvent event) {
						// TODO Auto-generated method stub
						if (actionId == EditorInfo.IME_ACTION_SEARCH) {
							hideSoftKeyboard();

							Thread thread = new Thread(new Runnable() {

								@Override
								public void run() {
									// TODO Auto-generated method stub

									performSearch();
								}
							});
							thread.start();
							return true;
						}
						return false;
					}
				});

		edtSearch.addTextChangedListener(new TextWatcher() {

			@Override
			public void onTextChanged(CharSequence s, int start, int before,
					int count) {
				// TODO Auto-generated method stub
				if (count > 0)
					btnSearch.setEnabled(true);
				else
					btnSearch.setEnabled(false);
			}

			@Override
			public void beforeTextChanged(CharSequence s, int start, int count,
					int after) {
				// TODO Auto-generated method stub

			}

			@Override
			public void afterTextChanged(Editable s) {
				// TODO Auto-generated method stub

			}
		});

		/** Button search */
		btnSearch = (Button) rootView.findViewById(R.id.btn_search);
		btnSearch.setEnabled(false);
		btnSearch.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				hideSoftKeyboard();

				Thread thread = new Thread(new Runnable() {

					@Override
					public void run() {
						// TODO Auto-generated method stub

						performSearch();
					}
				});
				thread.start();
			}
		});
	}

	/**
	 * dectect languge string
	 * 
	 * @throws LangDetectException
	 */
	public void detectStringLanguage(String text) throws LangDetectException {
		// detectlanguge
		dectector = DetectorFactory.create();
		dectector.append(text);
		try {
			ArrayList<Language> langlist = dectector.getProbabilities();
			for (Language language : langlist) {
				Log.d("LANGUAGE", language.lang);
				// LanguageSpeech lang = new LanguageSpeech();
				// HashMap<String, Locale> hash = lang.getLanguage();
				// listAdapter.getSpeaker().setLanguage(Locale.JAPANESE);
			}
		} catch (LangDetectException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}
